package main

import (
	"os"
	"fmt"
	"io/ioutil"
	"bufio"
	"strings"
	"strconv"
	"sync"
)

func  searchFile(dir string , files []os.FileInfo ,wg *sync.WaitGroup)  {
	wg.Add(1)
	defer wg.Done()

	for _ ,file := range  files {
		format := "[F] %s\n"
		newName := dir +DIR_SEP+ file.Name()
		if file.IsDir() && !hasIgnoreDir(file){
			format = "[D] %s\n"

			fs , err := ioutil.ReadDir(newName)
			if err != nil {
				fmt.Println("[ ReadDir err ]", newName ,err)
			}
			go searchFile(newName ,fs , wg)
		}
		if strings.Contains(strings.ToLower(newName),strings.ToLower(keyword)) {
			fmt.Printf(format,newName)
		}
	}
}


func  searchText(dir string , files []os.FileInfo , wg *sync.WaitGroup)  {
	wg.Add(1)
	defer  wg.Done()
	for _ , file := range files {
		newName := dir +DIR_SEP+ file.Name()
		//fmt.Println(newName)
		if !file.IsDir() {

			if float64(file.Size()) / 1024 / 1024 < *max_read_file_size  && !hasIgonreExt(file) {
				fd , err := os.OpenFile(newName,os.O_RDONLY,0)
				if err != nil {
					fmt.Println("[openFile] ",err)
				}
				scanner := bufio.NewScanner(fd)
				isBegin := false
				number := 1
				for scanner.Scan() {

					s := scanner.Text()
					if strings.Contains(strings.ToLower(s),strings.ToLower(keyword)) {
						if !isBegin {
							fmt.Println("-----------------------------------------------------------------------")
							fmt.Println(newName)
						}
						isBegin = true
						s := reg.ReplaceAllStringFunc(s, func(sub string) string {
							return  "[ "+sub+ " ]"
						})
						fmt.Println("["+ strconv.Itoa(number) + "]",s)
					}
					number += 1
				}
			}
			
		}else{
			if !hasIgnoreDir(file) {
				fs , err := ioutil.ReadDir(newName)
				if err != nil {
					fmt.Println("[searchText ReadDir err ]", newName ,err)
				}
				go searchText(newName ,fs , wg )
			}
		}

	}
}

func hasIgonreExt(file os.FileInfo) bool {
	for _ , ext := range ignoreExts  {
		if(strings.HasSuffix(strings.ToLower(file.Name()),ext)){
			return  true
		}
	}
	return  false
}

func hasIgnoreDir(file os.FileInfo) bool  {
	for  _ , dir := range ignoreDirs  {
		if dir == strings.ToLower(file.Name()) {
			return  true
		}
	}
	return  false
}
